home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / comm / rzsz0916.zip / ZMR.C < prev    next >
C/C++ Source or Header  |  1994-01-27  |  5KB  |  189 lines

  1. /*
  2.  * File: zmr.c
  3.  * Copyright 1988, 1994 Omen Technology Inc All Rights Reserved
  4.  *
  5.  *
  6.  * 
  7.  * This module implements ZMODEM Run Length Encoding, an
  8.  * extension that was not funded by the original Telenet
  9.  * development contract.
  10.  * 
  11.  *  This software may be freely used for educational (didactic
  12.  *  only) purposes.  This software may also be freely used to
  13.  *  support file transfer operations to or from licensed Omen
  14.  *  Technology products.  Use with other commercial or shareware
  15.  *  programs (Crosstalk, Procomm, etc.) REQUIRES REGISTRATION.
  16.  *
  17.  *  Any programs which use part or all of this software must be
  18.  *  provided in source form with this notice intact except by
  19.  *  written permission from Omen Technology Incorporated.
  20.  * 
  21.  * Use of this software for commercial or administrative purposes
  22.  * except when exclusively limited to interfacing Omen Technology
  23.  * products requires a per port license payment of $20.00 US per
  24.  * port (less in quantity).  Use of this code by inclusion,
  25.  * decompilation, reverse engineering or any other means
  26.  * constitutes agreement to these conditions and acceptance of
  27.  * liability to license the materials and payment of reasonable
  28.  * legal costs necessary to enforce this license agreement.
  29.  *
  30.  *
  31.  *        Omen Technology Inc
  32.  *        Post Office Box 4681
  33.  *        Portland OR 97208
  34.  *
  35.  *    This code is made available in the hope it will be useful,
  36.  *    BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
  37.  *    DAMAGES OF ANY KIND.
  38.  *
  39.  *    ZMODEM RLE compression and decompression functions
  40.  */
  41.  
  42. /* Send data subpacket RLE encoded with 32 bit FCS */
  43. zsdar32(buf, length, frameend)
  44. char *buf;
  45. {
  46.     register int c, l, n;
  47.     register unsigned long crc;
  48.  
  49.     crc = 0xFFFFFFFFL;  l = *buf++ & 0377;
  50.     if (length == 1) {
  51.         zsendline(l); crc = UPDC32(l, crc);
  52.         if (l == ZRESC) {
  53.             zsendline(1); crc = UPDC32(1, crc);
  54.         }
  55.     } else {
  56.         for (n = 0; --length >= 0; ++buf) {
  57.             if ((c = *buf & 0377) == l && n < 126 && length>0) {
  58.                 ++n;  continue;
  59.             }
  60.             switch (n) {
  61.             case 0:
  62.                 zsendline(l);
  63.                 crc = UPDC32(l, crc);
  64.                 if (l == ZRESC) {
  65.                     zsendline(0100); crc = UPDC32(0100, crc);
  66.                 }
  67.                 l = c; break;
  68.             case 1:
  69.                 if (l != ZRESC) {
  70.                     zsendline(l); zsendline(l);
  71.                     crc = UPDC32(l, crc);
  72.                     crc = UPDC32(l, crc);
  73.                     n = 0; l = c; break;
  74.                 }
  75.                 /* **** FALL THRU TO **** */
  76.             default:
  77.                 zsendline(ZRESC); crc = UPDC32(ZRESC, crc);
  78.                 if (l == 040 && n < 34) {
  79.                     n += 036;
  80.                     zsendline(n); crc = UPDC32(n, crc);
  81.                 }
  82.                 else {
  83.                     n += 0101;
  84.                     zsendline(n); crc = UPDC32(n, crc);
  85.                     zsendline(l); crc = UPDC32(l, crc);
  86.                 }
  87.                 n = 0; l = c; break;
  88.             }
  89.         }
  90.     }
  91.     xsendline(ZDLE); xsendline(frameend);
  92.     crc = UPDC32(frameend, crc);
  93.  
  94.     crc = ~crc;
  95.     for (length=4; --length >= 0;) {
  96.         zsendline((int)crc);  crc >>= 8;
  97.     }
  98. }
  99.  
  100.  
  101. /* Receive data subpacket RLE encoded with 32 bit FCS */
  102. zrdatr32(buf, length)
  103. register char *buf;
  104. {
  105.     register int c;
  106.     register unsigned long crc;
  107.     register char *end;
  108.     register int d;
  109.  
  110.     crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  111.     d = 0;    /* Use for RLE decoder state */
  112.     while (buf <= end) {
  113.         if ((c = zdlread()) & ~0377) {
  114. crcfoo:
  115.             switch (c) {
  116.             case GOTCRCE:
  117.             case GOTCRCG:
  118.             case GOTCRCQ:
  119.             case GOTCRCW:
  120.                 d = c;  c &= 0377;
  121.                 crc = UPDC32(c, crc);
  122.                 if ((c = zdlread()) & ~0377)
  123.                     goto crcfoo;
  124.                 crc = UPDC32(c, crc);
  125.                 if ((c = zdlread()) & ~0377)
  126.                     goto crcfoo;
  127.                 crc = UPDC32(c, crc);
  128.                 if ((c = zdlread()) & ~0377)
  129.                     goto crcfoo;
  130.                 crc = UPDC32(c, crc);
  131.                 if ((c = zdlread()) & ~0377)
  132.                     goto crcfoo;
  133.                 crc = UPDC32(c, crc);
  134.                 if (crc != 0xDEBB20E3) {
  135.                     zperr(badcrc);
  136.                     return ERROR;
  137.                 }
  138.                 Rxcount = length - (end - buf);
  139. #ifndef DSZ
  140.                 vfile("zrdatr32: %d %s", Rxcount,
  141.                   Zendnames[d-GOTCRCE&3]);
  142. #endif
  143.                 return d;
  144.             case GOTCAN:
  145.                 zperr("Sender Canceled");
  146.                 return ZCAN;
  147.             case TIMEOUT:
  148.                 zperr("TIMEOUT");
  149.                 return c;
  150.             default:
  151.                 zperr("Bad data subpacket");
  152.                 return c;
  153.             }
  154.         }
  155.         crc = UPDC32(c, crc);
  156.         switch (d) {
  157.         case 0:
  158.             if (c == ZRESC) {
  159.                 d = -1;  continue;
  160.             }
  161.             *buf++ = c;  continue;
  162.         case -1:
  163.             if (c >= 040 && c < 0100) {
  164.                 d = c - 035; c = 040;  goto spaces;
  165.             }
  166.             if (c == 0100) {
  167.                 d = 0;
  168.                 *buf++ = ZRESC;  continue;
  169.             }
  170.             d = c;  continue;
  171.         default:
  172.             d -= 0100;
  173.             if (d < 1)
  174.                 goto badpkt;
  175. spaces:
  176.             if ((buf + d) > end)
  177.                 goto badpkt;
  178.             while ( --d >= 0)
  179.                 *buf++ = c;
  180.             d = 0;  continue;
  181.         }
  182.     }
  183. badpkt:
  184.     zperr("Data subpacket too long");
  185.     return ERROR;
  186. }
  187.  
  188. /* End of zmr.c */
  189.